package com.south.base.test.arithmetic;

import org.junit.Test;

/**
 * @author Administrator
 * @date 2019/11/21 14:38
 */
public class BitOperation {
    /**
     * 颠倒给定的 32 位无符号整数的二进制位。
     */
    @Test
    public void reverseBits() {
        System.out.println(reverseBits(11));
    }

    public int reverseBits(int n) {
        int result = 0;
        for (int i = 0; i <= 32; i++) {
            // 1. 将给定的二进制数,由低到高位逐个取出
            // 1.1 右移 i 位,
            int tmp = n >> i;
            // 1.2  取有效位
            tmp = tmp & 1;
            // 2. 然后通过位运算将其放置到反转后的位置.
            tmp = tmp << (31 - i);
            // 3. 将上述结果再次通过运算结合到一起
            result |= tmp;
        }
        return result;
    }

    /**
     * 汉明重量
     * 输入是一个无符号整数，返回其二进制表达式中数字位数为 ‘1’ 的个数
     */
    @Test
    public void hammingWeight() {
        System.out.println(hammingWeight(11));
    }

    public int hammingWeight(int n) {
        int result = 0;
        for (int i = 0; i < 32; i++) {
            // 1. 将给定的二进制数,由低到高位逐个取出
            // 1.1 右移 i 位,
            int tmp = n >> i;
            // 1.2  取有效位
            result += tmp & 1;
        }
        return result;
    }

    /**
     * 给定一个正整数，检查他是否为交替位二进制数：换句话说，就是他的二进制数相邻的两个位数永不相等。
     */
    @Test
    public void hasAlternatingBits() {
        System.out.println(hasAlternatingBits(5));
        System.out.println(hasAlternatingBits(7));
        System.out.println(hasAlternatingBits(11));
        System.out.println(hasAlternatingBits(10));
    }

    public boolean hasAlternatingBits(int n) {
        boolean result = false;
        boolean flag = false;
        int tmp = 0;
        for (int i = 31; i >= 0; i--) {
            if (!flag) {
                flag = ((n >> i) & 1) == 1;
            }
            if (!flag) {
                continue;
            }
            int current = (n >> i) & 1;
            result = current == tmp;
            tmp = current;
            if (result) {
                break;
            }
        }
        return !result;
    }
}
